package com.aaa.mbs.service.impl;

import com.aaa.common.bo.CouponHistory;
import com.aaa.common.constants.BusinessConstants;
import com.aaa.common.constants.ExceptionConstant;
import com.aaa.common.util.CustomException;
import com.aaa.mbs.dao.AccountStatementDao;
import com.aaa.mbs.entity.AccountStatement;
import com.aaa.mbs.entity.Member;
import com.aaa.mbs.dao.MemberDao;

import com.aaa.mbs.service.AccountStatementService;
import com.aaa.mbs.service.MemberService;
import com.aaa.mbs.service.RemoteCouponHistoryService;
import com.aaa.mbs.util.MdzwUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.shiro.crypto.hash.Sha512Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import com.aaa.common.util.Result;
import com.aaa.common.constants.ReturnStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

/**
 * (Member)表服务实现类
 *
 * @author makejava
 * @since 2020-12-04 20:52:30
 */
@Service("memberService")
@Transactional
public class MemberServiceImpl implements MemberService {
    @Resource
    private MemberDao memberDao;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 会员账号流水记录服务
     */
    @Resource
    private AccountStatementDao accountStatementDao;

    private RemoteCouponHistoryService remoteCouponHistoryService;

    @Override
    public Member queryByUserName(String userName) {
        Member paraMember=new Member();
        //设置用户名
        paraMember.setUsername(userName);
        //设置状态为有效
        paraMember.setStatus(1);
        List<Member> members = memberDao.queryAll(paraMember);
        if(members!=null && members.size()>0){
            return members.get(0);
        }
        return null;
    }

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public Member queryById(Integer id) {
        return this.memberDao.queryById(id);
    }
    /**
     * 通过实体作为筛选条件查询
     *
     * @param member 实例对象
     * @return 对象列表
     */
    @Override
    public Result queryAll(Member member){
        List<Member> members = memberDao.queryAll(member);
        return new Result(ReturnStatus.SUCCESS.getReturnCode(),
                ReturnStatus.SUCCESS.getReturnMsg(), members);
    }
    /**
     * 联合查询分页作为筛选条件查询
     *
     * @param map 实例对象
     * @return 对象列表
     */
    @Override
    public Result queryAllMap(int pageNo, int pageSize, Map map){
        if(pageNo==0||pageSize==0){
            throw new CustomException (ExceptionConstant.INVALID_ARGUMENT.getErrorCode(),
                    ExceptionConstant.INVALID_ARGUMENT.getErrorMessage());
        }
        //分页
        PageHelper.startPage(pageNo,pageSize);
        PageInfo<Map> pageInfo = new PageInfo<>(memberDao.queryAllMap(map));
        return new Result(ReturnStatus.SUCCESS.getReturnCode(),
                ReturnStatus.SUCCESS.getReturnMsg(), pageInfo);
    }
    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @Override
    public List<Member> queryAllByLimit(int offset, int limit) {
        return this.memberDao.queryAllByLimit(offset, limit);
    }


    /**
     * 校验验证码
     * @return
     */
    private Result checkyanZhengMa(Member member){
        //从redis中获取验证码
        String yanZhengMa = null;
        try {
            yanZhengMa = redisTemplate.opsForValue().get(member.getPhoneNum()).toString();
        } catch (Exception e) {
            return new Result(ReturnStatus.FAIL.getReturnCode(),
                    ReturnStatus.FAIL.getReturnMsg(), "验证码错误！");
        }
        if(null==yanZhengMa){
            return new Result(ReturnStatus.FAIL.getReturnCode(),
                    ReturnStatus.FAIL.getReturnMsg(), "验证码错误！");
        }
//        System.out.println(yanZhengMa);
//        System.out.println(member.getToken());
        String s = new String(yanZhengMa);
        String s1 = new String(member.getToken());
        if(!s.equals(s1)){
//            System.out.println("验证码错误");
            return new Result(ReturnStatus.FAIL.getReturnCode(),
                    ReturnStatus.FAIL.getReturnMsg(), "验证码错误！");
        }
        return new Result(ReturnStatus.SUCCESS.getReturnCode(),
                ReturnStatus.SUCCESS.getReturnMsg(), "验证码正确！");
    }

    /**
     * 新增数据
     *
     * @param member 实例对象
     * @return 实例对象
     */
    @Override
    public Result insert(Member member) {
        //校验验证码
        Result result = this.checkyanZhengMa(member);
        //验证码错误执行的代码
        if(result.getCode()==3000){
            return result;
        }
        //获取会员注册输入的密码
        String password = member.getPassword();
        //随机盐值
        String passwordSlat = UUID.randomUUID().toString().substring(0, 10);
        //生成加密密码
        Sha512Hash sha512Hash  =new Sha512Hash(password,passwordSlat,1024);
        //再次设置，覆盖原密码
        member.setPassword(sha512Hash.toString());
        //设置盐值
        member.setPwSalt(passwordSlat);
        //设置启用状态  0禁用  1启用
        member.setStatus(1);
        //设置成长值初始值
        member.setGrowth(0.0);
        member.setAccountBalance(0.0);
        member.setIntegration(0);
        member.setMemberLevelId(1);
        member.setHistoryIntegration(0);
        int insert = this.memberDao.insert(member);
        //新用户优惠券赠送
        CouponHistory couponHistory = new CouponHistory();
        //固定200元优惠券-新用户注册 id为1
        couponHistory.setCouponId(1L);
        // couponHistory.setUseTime(); 必须为空
        couponHistory.setMemberId(member.getId());
        couponHistory.setCouponCode("100001");
        couponHistory.setGetType(BusinessConstants.CouponGeTtYPE.HTZS);
        couponHistory.setUseStatus(1);
        remoteCouponHistoryService.insert(couponHistory);
        if(insert<0){
            throw new CustomException(ExceptionConstant.SYS_EXCEPTION.getErrorCode(),
                    ExceptionConstant.SYS_EXCEPTION.getErrorMessage());
        }
        return new Result(ReturnStatus.SUCCESS.getReturnCode(),
                ReturnStatus.SUCCESS.getReturnMsg(), "注册成功");
    }

    /**
     * 修改数据
     *
     * @param member 实例对象
     * @return 实例对象
     */
    @Override
    public Result update(Member member) {
        //判断会员金额是否为空
        if(member.getAccountBalance()!=null){
            //实例化会员流水对象
            AccountStatement accountStatement = new AccountStatement();
            //设置流水类型为充值   1为支付   2为充值
            accountStatement.setTypeId(2);
            //设置会员id
            accountStatement.setClientId(member.getId());
            //判断是否是第一次充值
            List<AccountStatement> accountStatements = accountStatementDao.queryAll(accountStatement);
            if(accountStatements==null){
                //第一次充值
                this.updateMemberLevel(member);
            }
        }
        //判断是否传入密码
        if(member.getPassword()!=null){
            Result result = this.checkyanZhengMa(member);
            if(result.getCode()==3000){
                return result;
            }
        }
        //获取会员注册输入的密码
        String password = member.getPassword();
        //随机盐值
        String passwordSlat = UUID.randomUUID().toString().substring(0, 10);
        //生成加密密码
        Sha512Hash sha512Hash  =new Sha512Hash(password,passwordSlat,1024);
        //再次设置，覆盖原密码
        member.setPassword(sha512Hash.toString());
        //设置盐值
        member.setPwSalt(passwordSlat);
        //调用更新方法
        int update = this.memberDao.update(member);
        if(update<0){
            throw new CustomException(ExceptionConstant.SYS_EXCEPTION.getErrorCode(),
                    ExceptionConstant.SYS_EXCEPTION.getErrorMessage());
        }
        return new Result(ReturnStatus.SUCCESS.getReturnCode(),
                ReturnStatus.SUCCESS.getReturnMsg(), "提交成功");
    }

    /**
     * 首充更新会员等级
     * @param member
     * @return
     */
    private Member updateMemberLevel(Member member){
        //获取前端传过来的会员充值后的金额
        Double accountBalanceNew = member.getAccountBalance();
        //获取会员充值前的金额
        Double accountBalanceOld = this.queryById(member.getId()).getAccountBalance();
        //获取充值的金额
        Double recharge = accountBalanceNew-accountBalanceOld;
        if(recharge==0){
            return member;
        }
        //会员一次性充值1000金卡会员，3000白金会员，5000钻石会员， 10000星耀会员
        if(recharge>=10000){
            member.setMemberLevelId(10);
        }else if(recharge>=5000){
            member.setMemberLevelId(4);
        }else if(recharge>=3000){
            member.setMemberLevelId(3);
        }else if(recharge>=1000){
            member.setMemberLevelId(2);
        }else{
            member.setMemberLevelId(1);
        }
        return member;
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.memberDao.deleteById(id) > 0;
    }

    //获取openid
    @Override
    public Map<String, Object> getWxUserOpenid(String code, String APPID, String APPSecret) {
        //拼接url
        StringBuilder url = new StringBuilder("https://api.weixin.qq.com/sns/jscode2session?");
        url.append("appid=");//appid设置
        url.append(APPID);
        url.append("&secret=");//secret设置
        url.append(APPSecret);
        url.append("&js_code=");//code设置
        url.append(code);
        url.append("&grant_type=authorization_code");
        Map<String, Object> map = null;
        try {
            HttpClient client = HttpClientBuilder.create().build();//构建一个Client
            HttpGet get = new HttpGet(url.toString());    //构建一个GET请求
            HttpResponse response = client.execute(get);//提交GET请求
            HttpEntity result = response.getEntity();//拿到返回的HttpResponse的"实体"
            String content = EntityUtils.toString(result);
            System.out.println(content);//打印返回的信息
//            JSONObject res = new JSONObject(content);//把信息封装为json
            JSONObject res = JSONObject.fromObject(content);//把信息封装为json
            //把信息封装到map
            map = MdzwUtils.parseJSON2Map(res);//这个小工具的代码在下面
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }
}